package com.ziytek.web.citizen.quartz.impl;

import com.ziytek.web.citizen.constant.NumConstant;
import com.ziytek.web.citizen.model.bean.CronJob;
import com.ziytek.web.citizen.model.rsp.R;
import com.ziytek.web.citizen.quartz.QuartzService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @author fengh
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class QuartServiceImpl implements QuartzService {
    private final Scheduler scheduler;

    private static final String DEFAULT_JOB_GROUP = "default_job_group";
    private static final String DEFAULT_TRIGGER_GROUP = "default_trigger_group";
    private static final String TRIGGER_PRE = "Trigger_";

    @Override
    public R addCronJob(String jobName, String cron, String jobClassName, String triggerName, int seconds) {
        try {
            var jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);
            if (scheduler.checkExists(jobKey)) {
                return R.fail("【添加定时任务】该作业已存在");
            }
            //构建job
            var job = JobBuilder
                    .newJob((Class<? extends Job>) Class.forName(jobClassName))
                    .withIdentity(jobKey)
                    .build();
            //Cron表达式定时构造器
            //var cron1 = "*/10 * * * * ?";
            // CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(cron);
            var now = new Date();
            var count = seconds / 10;
            var interval = seconds % 10;
            count = interval == 0 ? count : count + 1;
            //log.info("添加定时任务，任务次数：{}", count);

            var endTime = Date.from(new Date().toInstant().plusSeconds(seconds + 7));
            //构建Trigger
            var trigger = TriggerBuilder.newTrigger()
                    .withIdentity(TriggerKey.triggerKey(TRIGGER_PRE + triggerName, DEFAULT_TRIGGER_GROUP))
                    // .withSchedule(cronSchedule)
                    //.withSchedule(scheduleBuilder)
                    //.startNow()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(10)
                            .withRepeatCount(count + 1))
                    //.startAt(startTime)
                    // 设置开始时间
                    .startAt(now)
                    // 设置结束时间
                    //.endAt(endTime)
                    .build();

            //log.info("添加定时任务，任务名称：{}, seconds：{}, 结束时间：{}", jobName, seconds, endTime);
            //启动调度
            scheduler.scheduleJob(job, trigger);
            scheduler.start();
        } catch (Exception e) {
            return R.fail("创建定任务失败，原因是：" + e.getMessage());
        }
        return R.success("创建定时任务成功！" + jobName + ",任务表达式：" + cron);
    }

    @Override
    public R addCronJob(CronJob cronJob) {
        try {
            var jobKey = JobKey.jobKey(cronJob.getJobName(), DEFAULT_JOB_GROUP);
            if (scheduler.checkExists(jobKey)) {
                return R.fail("【添加定时任务】该作业已存在");
            }

            //构建job
            var job = JobBuilder
                    .newJob((Class<? extends Job>) Class.forName(cronJob.getJobClassName()))
                    .withIdentity(jobKey)
                    .usingJobData(cronJob.getDataMap())
                    .build();

            var countNum = cronJob.getExpectedTimeSecond() / NumConstant.INT_TEN;
            var interval = cronJob.getExpectedTimeSecond() % NumConstant.INT_TEN;
            var count = interval == NumConstant.INT_ZERO ? countNum + NumConstant.INT_ONE : countNum + NumConstant.INT_TWO;
            if (null != cronJob.getOrderOneFirstError() && cronJob.getOrderOneFirstError()) {
                count = NumConstant.INT_ZERO;
            }

            //var count = interval == NumConstant.INT_ZERO ? countNum : countNum + NumConstant.INT_ONE;
            //log.info("添加定时任务,任务次数:{},cronJob {}", count, cronJob);

//            var interruptKey = cronJob.getCacheKey();
//            var interruptStats = cachePutOrGet.getInterruptStatsCache(interruptKey);
//            if (interruptStats != null) {
//                count = interval == NumConstant.INT_ZERO ? countNum + NumConstant.INT_TWO : countNum + NumConstant.INT_THREE;
//                log.info("[中断]添加定时任务:{}", count);
//            }

            //构建Trigger
            var trigger = TriggerBuilder.newTrigger()
                    .withIdentity(TriggerKey.triggerKey(TRIGGER_PRE + cronJob.getTriggerName(), DEFAULT_TRIGGER_GROUP))
                    .startNow()
                    //.startAt(DateUtils.addSeconds(nowTime, 3))
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(10)
                            .withRepeatCount(count))
                    .build();


            //log.info("添加定时任务：任务次数,{} {}, seconds：{}", count, cronJob.getJobName(), cronJob.getExecuteTime());
            //启动调度
            scheduler.scheduleJob(job, trigger);
            scheduler.start();
        } catch (Exception e) {
            return R.fail("创建定任务失败，原因是：" + e.getMessage());
        }
        return R.success("创建定时任务成功！" + cronJob.getJobName() + ",任务表达式：" + cronJob.getCron());
    }

    @Override
    public R updateCronJob(String jobName, String cron, String jobClassName) {
        return null;
    }

    @Override
    public R pauseCronJob(String jobName) {
        try {
            var jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);
            if (!scheduler.checkExists(jobKey)) {
                return R.fail("【暂停定时任务】该作业不存在");
            }
            // 暂停任务
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            return R.fail("【暂停定时任务失败】原因是：" + e.getMessage());
        }

        return R.success("暂停定时任务成功！" + jobName);
    }

    @Override
    public R resumeCronJob(String jobName) {
        try {
            // 通过任务名和任务组名获取jobKey
            var jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);
            if (!scheduler.checkExists(jobKey)) {
                return R.fail("【继续定时任务】该作业不存在");
            }
            // 继续任务
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            return R.fail("【继续定时任务失败】原因是：" + e.getMessage());
        }
        return R.success("继续定时任务成功！" + jobName);
    }

    @Override
    public R deleteCronJob(String jobName) {
        try {
            // TriggerKey 定义了trigger的名称和组别 ，通过任务名和任务组名获取TriggerKey
            var triggerKey = TriggerKey.triggerKey(jobName, DEFAULT_JOB_GROUP);
            // 停止触发器
            scheduler.resumeTrigger(triggerKey);
            // 移除触发器
            scheduler.unscheduleJob(triggerKey);
            // 移除任务
            scheduler.deleteJob(JobKey.jobKey(jobName, DEFAULT_JOB_GROUP));
        } catch (SchedulerException e) {
            return R.fail("【删除定时任务失败】原因是：" + e.getMessage());
        }

        return R.success("删除定时任务成功！" + jobName);
    }
}
